<!--主页-->
<template>
  <el-container direction="vertical" class="wrapper">
    <v-header />
    <el-container direction="vertical" class="scroll-cont">
      <el-scrollbar>
        <el-main>
          <div class="article">
            <h1 class="title">Cesium-for-Vue</h1>
            <div class="content">基于Vue 3，面向Cesium开发者的参考示例</div>
            <div class="content">
              Cesium是一个基于JavaScript编写的使用WebGL的地图引擎。Cesium支持3D,2D,2.5D形式的地图展示，可以自行绘制图形，高亮区域，并提供良好的触摸支持，且支持绝大多数的浏览器和mobile。
            </div>
          </div>
          <div class="main-cont">
            <div class="cesium-map" id="cesiumMap">
              <div class="cesium" id="cesium"></div>
              <div class="mouse-info" id="mouseInfo"></div>
              <div
                id="tempStatis"
                style="z-index: 100"
                v-if="current == 'temperature'"
              ></div>
              <video
                v-if="current == 'video'"
                id="video"
                style="display: none"
                muted=""
                loop=""
                crossorigin=""
                controls=""
              >
                <source src="media/fly.mp4" type="video/mp4" />
              </video>
            </div>
            <div class="toolbar" v-if="current == 'layer'">
              <el-button
                type="primary"
                v-for="item in layers"
                :key="item.key"
                @click="addLayer(item.key)"
                >{{ item.label }}</el-button
              >
            </div>
            <div class="toolbar" v-if="current == 'terrain'">
              <el-button
                type="primary"
                v-for="item in terrains"
                :key="item.key"
                @click="terrainProvide(item.key)"
                >{{ item.label }}</el-button
              >
            </div>
            <div class="toolbar" v-if="current == 'arrow'">
              <el-button
                type="primary"
                v-for="item in arrows"
                :key="item.key"
                @click="handleArrow(item.key)"
                >{{ item.label }}</el-button
              >
            </div>
            <div class="toolbar" v-if="current == 'modelType'">
              <el-button
                type="primary"
                v-for="item in modelTypes"
                :key="item.key"
                @click="handleModelType(item.key)"
                >{{ item.label }}</el-button
              >
            </div>
            <div class="cruise-dialog" v-if="current == 'cruise'">
              <div class="info-box">
                <div>设备编号：</div>
              </div>
              <div class="info-box">
                <div>采集点经度：</div>
                <div>采集点纬度：</div>
                <div>采集点高度：</div>
              </div>
              <div class="info-box">
                <div>1分钟车辆数：</div>
              </div>
              <div class="video-box">
                <video
                  id="video"
                  width="160"
                  height="160"
                  src="media/fly.mp4"
                  controls
                  autoplay
                ></video>
              </div>
            </div>
            <div class="mask" id="loadingOverlay">
              <h1>Loading...</h1>
            </div>
            <div class="describe">{{ describe }}</div>
            <div class="swiper-cont">
              <swiper
                class="swiper"
                :style="{
                  '--swiper-navigation-color': '#de4a4a',
                  '--swiper-pagination-color': '#de4a4a',
                }"
                :navigation="true"
                :pagination="{
                  clickable: true,
                }"
                :breakpoints="{
                  '640': {
                    slidesPerView: 3,
                    spaceBetween: 10,
                  },
                  '768': {
                    slidesPerView: 5,
                    spaceBetween: 10,
                  },
                  '1024': {
                    slidesPerView: 7,
                    spaceBetween: 10,
                  },
                }"
                :modules="modules"
              >
                <swiper-slide
                  class="swiper-slide"
                  v-for="(item, index) in list"
                  :key="index"
                >
                  <img :src="item.path" />
                  <div class="label">{{ item.name }}</div>
                  <span class="icon" @click="gotoPage(item)">
                    <el-icon><Search /></el-icon>
                  </span>
                </swiper-slide>
              </swiper>
            </div>
          </div>
        </el-main>
        <v-footer />
      </el-scrollbar>
    </el-container>
  </el-container>
</template>
<script>
import vHeader from '@/components/header/index'
import vFooter from '@/components/footer/index'
import BasicCesium from '@/utils/cesium'
import flightDataset from './flightData'
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Pagination, Navigation } from 'swiper/modules'
import 'swiper/css'
import 'swiper/css/pagination'
import 'swiper/css/navigation'
import viewerMixins from '@/mixins/index'
import Constant from '@/utils/constant'
import { list, layers, terrains, arrows, modelTypes, loading } from './datas'
import Style from '@/utils/style'
import Paint from '@/utils/paint'
import Temperature from '@/utils/temperature'
import Video from '@/utils/video'
import Sunshine from '@/utils/sunshine'
import Rain from '@/utils/rain'
import Scatter from '@/utils/scatter'
import Arrow from '@/utils/arrow'
import CircleFly from '@/utils/circle-fly'
import Grain from '@/utils/grain'
import ModelType from '@/utils/modelType'
import Metaptosis from '@/utils/metaptosis'
import Geometric from '@/utils/geometric'
import Flypath from '@/utils/fly-path'
import Emutiple from '@/utils/emutiple'
import Ellipse from '@/utils/ellipse'
import Ebar from '@/utils/ebar'
import Czml from '@/utils/czml'
import Cruise from '@/utils/cruise'
import ControlFly from '@/utils/control-fly'

export default {
  components: {
    vHeader,
    vFooter,
    Swiper,
    SwiperSlide,
  },
  mixins: [viewerMixins],
  data() {
    return {
      modules: [Pagination, Navigation],
      describe: 'Cesium星球大战',
      current: null,
      basicCesium: null,
      list: list,
      layers: layers,
      terrains: terrains,
      arrows: arrows,
      modelTypes: modelTypes,
      loading: loading,
      arrow: null,
      modelType: null,
      fireworks: null,
    }
  },
  methods: {
    async initMap() {
      this.basicCesium = new BasicCesium('cesium', {
        shouldAnimate: true,
        animation: true,
        timeline: true,
      })
      const viewer = this.basicCesium.viewer
      const flightData = flightDataset

      const timeStepInSeconds = 30
      const totalSeconds = timeStepInSeconds * (flightData.length - 1)
      const start = Cesium.JulianDate.fromIso8601('2020-03-09T23:10:00Z')
      const stop = Cesium.JulianDate.addSeconds(
        start,
        totalSeconds,
        new Cesium.JulianDate()
      )
      viewer.clock.startTime = start.clone()
      viewer.clock.stopTime = stop.clone()
      viewer.clock.currentTime = start.clone()
      viewer.timeline.zoomTo(start, stop)
      // Speed up the playback speed 50x.
      viewer.clock.multiplier = 50
      // Start playing the scene.
      viewer.clock.shouldAnimate = true

      // The SampledPositionedProperty stores the position and timestamp for each sample along the radar sample series.
      const positionProperty = new Cesium.SampledPositionProperty()

      for (let i = 0; i < flightData.length; i++) {
        const dataPoint = flightData[i]

        // Declare the time for this individual sample and store it in a new JulianDate instance.
        const time = Cesium.JulianDate.addSeconds(
          start,
          i * timeStepInSeconds,
          new Cesium.JulianDate()
        )
        const position = Cesium.Cartesian3.fromDegrees(
          dataPoint.longitude,
          dataPoint.latitude,
          dataPoint.height
        )
        // Store the position along with its timestamp.
        // Here we add the positions all upfront, but these can be added at run-time as samples are received from a server.
        positionProperty.addSample(time, position)

        viewer.entities.add({
          description: `Location: (${dataPoint.longitude}, ${dataPoint.latitude}, ${dataPoint.height})`,
          position: position,
          point: { pixelSize: 10, color: Cesium.Color.RED },
        })
      }
      this.loadModel(positionProperty, viewer, start, stop)
    },
    async loadModel(positionProperty, viewer, start, stop) {
      try {
        // Load the glTF model from Cesium ion.
        const airplaneEntity = viewer.entities.add({
          availability: new Cesium.TimeIntervalCollection([
            new Cesium.TimeInterval({ start: start, stop: stop }),
          ]),
          position: positionProperty,
          // Attach the 3D model instead of the green point.
          model: {
            uri: 'glb/drone.glb',
            minimumPixelSize: 160,
            maximumScale: 20000,
          },
          // Automatically compute the orientation from the position.
          orientation: new Cesium.VelocityOrientationProperty(positionProperty),
          path: new Cesium.PathGraphics({ width: 3 }),
        })

        viewer.trackedEntity = airplaneEntity
      } catch (error) {
        console.log(error)
      }
    },
    gotoPage(item) {
      this.describe = item.describe
      this.current = item.id
      this.resetDom()
      switch (item.id) {
        case 'basic':
          this.basicMap('cesium')
          break
        case 'layer':
          this.basicCesium = this.basicMap('cesium', {})
          break
        case 'terrain':
          this.basicCesium = this.basicMap('cesium', {})
          break
        case 'eyemap':
          this.openEyemap()
          break
        case 'style':
          let dom = document.querySelector('#cesium')
          dom.className = 'cesium cesium-lighter'
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
            infoBox: true,
          })
          new Style(this.basicCesium.viewer)
          break
        case 'paint':
          this.basicCesium = this.basicMap('cesium', {})
          new Paint(this.basicCesium)
          break
        case 'temperature':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Temperature(this.basicCesium)
          })
          break
        case 'video':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Video(this.basicCesium)
          })
          break
        case 'sunshine':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Sunshine(this.basicCesium)
          })
          break
        case 'rain':
          this.basicCesium = this.basicMap('cesium', {
            skyAtmosphere: new Cesium.SkyAtmosphere(),
          })
          this.$nextTick(() => {
            new Rain(this.basicCesium)
          })
          break
        case 'scatter':
          this.basicCesium = this.basicMap('cesium', {})
          new Scatter(this.basicCesium)
          break
        case 'arrow':
          this.basicCesium = this.basicMap('cesium', {})
          this.arrow = new Arrow(this.basicCesium)
          break
        case 'circleFly':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new CircleFly(this.basicCesium)
          })
          break
        case 'grain':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Grain(this.basicCesium)
          })
          break
        case 'modelType':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            this.modelType = new ModelType(this.basicCesium)
          })
          break
        case 'metaptosis':
          this.basicCesium = this.basicMap('cesium', {})
          this.$nextTick(() => {
            new Metaptosis(this.basicCesium)
          })
          break
        case 'geometric':
          this.basicCesium = this.basicMap('cesium', {})
          this.$nextTick(() => {
            new Geometric(this.basicCesium)
          })
          break
        case 'flypath':
          this.basicCesium = this.basicMap('cesium', {})
          this.$nextTick(() => {
            new Flypath(this.basicCesium)
          })
          break
        case 'emutiple':
          this.basicCesium = this.basicMap('cesium', {})
          this.$nextTick(() => {
            this.emutiple = new Emutiple(this.basicCesium)
          })
          break
        case 'ellipse':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Ellipse(this.basicCesium)
          })
          break
        case 'ebar':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Ebar(this.basicCesium)
          })
          break
        case 'czml':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Czml(this.basicCesium)
          })
          break
        case 'cruise':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new Cruise(this.basicCesium)
          })
          break
        case 'controlFly':
          this.basicCesium = this.basicMap('cesium', {
            shouldAnimate: true,
            animation: true,
            timeline: true,
          })
          this.$nextTick(() => {
            new ControlFly(this.basicCesium)
          })
          break
      }
    },
    resetDom() {
      let dom = document.querySelector('#cesium')
      let main = document.querySelector('#cesiumMap')
      if (dom) {
        let clone = dom.cloneNode()
        dom.remove()
        main.appendChild(clone)
      }
      let eyeDom = document.querySelector('#hawkEyeMap')
      if (eyeDom) eyeDom.remove()
      dom.className = 'cesium'
    },
  },
  mounted() {
    this.initMap()
  },
}
</script>
<style lang="scss" scoped>
@import './style.scss';
</style>
<style lang="scss">
@import '@/styles/cesium.scss';
.cruise-dialog {
  position: absolute;
  right: 50%;
  top: 1px;
  transform: translateX(355px);
  background: #fff;
  padding: 5px;
}
.info-box {
  font-size: 14px;
  line-height: 22px;
  margin-bottom: 15px;
  text-align: left;
}
</style>